/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * 2. The name "Antonio W. Lagnada" must not be used to endorse or promote
 * products derived from this software without prior written permission. For
 * written permission, please contact tony@lagnada.com
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANTONIO W.
 * LAGNADA OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *  
 */
package org.j2ee.example.web.multiaction;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.mvc.multiaction.AbstractUrlMethodNameResolver;

/**
 * PropertiesMethodNameResolver
 * 
 * @author Antonio W. Lagnada
 */
public class PropertiesMethodNameResolver extends AbstractUrlMethodNameResolver {

    public static final String SUCCESS_VIEW = "successView";

    public static final String HANDLER = "handler";

    //

    protected Map<String, Properties> m_mappings = new HashMap<String, Properties>();

    protected PathMatcher m_pathMatcher = new AntPathMatcher();

    //

    public PropertiesMethodNameResolver() {
        super();
    }

    /**
     * Set explicit URL to method name mappings through a Properties object.
     * 
     * @param mappings Properties with URL as key and method name as value
     */
    @Required
    public void setMappings(Map<String, Properties> mappings) {
        m_mappings = mappings;
    }

    /**
     * Set the PathMatcher implementation to use for matching URL paths against registered URL patterns. Default is
     * AntPathMatcher.
     * 
     * @see org.springframework.util.AntPathMatcher
     */
    public void setPathMatcher(PathMatcher pathMatcher) {
        m_pathMatcher = pathMatcher;
    }

    @Override
    protected String getHandlerMethodNameForUrlPath(String urlPath) {
        Properties methodProperties = m_mappings.get(urlPath);
        if (methodProperties != null) {
            return methodProperties.getProperty(HANDLER);
        }

        for (String registeredPath : m_mappings.keySet()) {
            if (m_pathMatcher.match(registeredPath, urlPath)) {
                methodProperties = m_mappings.get(registeredPath);
                return methodProperties.getProperty(HANDLER);
            }
        }

        return null;
    }

    public String getSuccessViewNameForUrlPath(String urlPath) {
        return this.getViewNameForUrlPath(SUCCESS_VIEW, urlPath);
    }

    public String getViewNameForUrlPath(String viewName, String urlPath) {
        Properties methodProperties = m_mappings.get(urlPath);
        if (methodProperties != null) {
            return methodProperties.getProperty(viewName);
        }

        for (String registeredPath : m_mappings.keySet()) {
            if (m_pathMatcher.match(registeredPath, urlPath)) {
                methodProperties = m_mappings.get(registeredPath);
                return methodProperties.getProperty(viewName);
            }
        }

        return null;
    }

}
